package net.borderwars.userserver;

import javax.swing.tree.DefaultMutableTreeNode;
import java.sql.*;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;

/**
 * @author ehubbard
 *         Date: Aug 15, 2005
 *         Time: 4:04:39 PM
 */
public class HTMLInterface {

    private String user;
    private StringBuffer buttonText = null;
    private DefaultMutableTreeNode root = null;
    private String treeString = null;
    private HashSet<DefaultMutableTreeNode> collaspedSet = new HashSet<DefaultMutableTreeNode>();

    static HashSet<Connection> connections = null;
    private DefaultMutableTreeNode publicBots;
    private DefaultMutableTreeNode testBots;
    private DefaultMutableTreeNode productionBots;
    private static PreparedStatement getBotsOwnedBy;
    private static PreparedStatement getBotsByOwnerAndTest;
    private boolean editEnabled = false;
    private String selectedBot;
    private Connection con;
    private static PreparedStatement getCodeByBot;
    private String code;

    public void close() throws SQLException {
        con.close();
    }

    private static Connection getConnection() throws SQLException, ClassNotFoundException {
//
//        if(connections == null || connections.size() ==0) {
//            connections = new HashSet<Connection>();
        Class.forName("com.mysql.jdbc.Driver");
        Connection c;
        c = DriverManager.getConnection("jdbc:mysql://localhost/borderwars", "borderwars", "unknown");
        prepareStatements(c);
//            connections.add(c);
//        }
//        Connection c = connections.iterator().next();
//        connections.remove(c);
        return (c);
    }

    private static void prepareStatements(Connection c) throws SQLException {
        getBotsOwnedBy = c.prepareStatement("select name from robots where owner =?");
        getBotsByOwnerAndTest = c.prepareStatement("select name from robots where owner=? and testing=?");
        getCodeByBot = c.prepareStatement("select source from robots where name=?");

    }

    private static void releaseConnection(Connection c) {
        connections.add(c);
    }

    public HTMLInterface(String user) throws SQLException, ClassNotFoundException {
        this.user = user;
        root = makeNode(user);
        publicBots = makeNode("Public Robots");
        testBots = makeNode("Robots in Testing");
        productionBots = makeNode("Robots in Production");
        con = getConnection();

        root.add(publicBots);
        root.add(testBots);
        root.add(productionBots);
        loadPublicBots();
        loadProductionBots();
        loadTestingBots();

        collaspedSet.remove(root);
    }

    HashMap<Object, DefaultMutableTreeNode> nodesByUser = new HashMap<Object, DefaultMutableTreeNode>();
    HashMap<String, DefaultMutableTreeNode> nodesByName = new HashMap<String, DefaultMutableTreeNode>();

    private void loadPublicBots() throws SQLException, ClassNotFoundException {
        Connection c = getConnection();
        getBotsOwnedBy.setString(1, "");
        ResultSet rs = getBotsOwnedBy.executeQuery();
        while (rs.next()) {
            publicBots.add(makeNode(rs.getString(1)));
        }
    }

    private void loadProductionBots() throws SQLException, ClassNotFoundException {
        Connection c = getConnection();
        getBotsByOwnerAndTest.setString(1, user);
        getBotsByOwnerAndTest.setBoolean(2, false);
        ResultSet rs = getBotsByOwnerAndTest.executeQuery();
        while (rs.next()) {
            productionBots.add(makeNode(rs.getString(1)));
        }
    }

    private void loadTestingBots() throws SQLException, ClassNotFoundException {
        Connection c = getConnection();
        getBotsByOwnerAndTest.setString(1, user);
        getBotsByOwnerAndTest.setBoolean(2, true);
        ResultSet rs = getBotsByOwnerAndTest.executeQuery();
        while (rs.next()) {
            testBots.add(makeNode(rs.getString(1)));
        }
    }

    private DefaultMutableTreeNode makeNode(Object o) {
        DefaultMutableTreeNode rtn = new DefaultMutableTreeNode(o);
        nodesByUser.put(o, rtn);
        collaspedSet.add(rtn);
        nodesByName.put(o.toString(), rtn);
        return (rtn);
    }

    public void treeClick(String name) throws SQLException {
        treeString = null;
        DefaultMutableTreeNode dmtn = nodesByName.get(name);
        boolean currentToggle = isCollasped(dmtn);
        setCollapsed(!currentToggle, dmtn);

        if (dmtn.isLeaf() || dmtn.getChildCount() == 0) { // if this is a leaf robot
            editEnabled = true;
            selectedBot = dmtn.toString();
            loadCode();
        }

    }

    private void loadCode() throws SQLException {
        getCodeByBot.setString(1, selectedBot);
        //  getCodeByBot.setString(2, selectedBot);
        ResultSet rs = getCodeByBot.executeQuery();
        rs.next();
        code = rs.getString(1);
    }

    public String getTreeView() {
        if (treeString == null) {
            StringBuffer rtn = new StringBuffer(200);
            makeString(root, rtn, 0);
            treeString = rtn.toString();
        }
        return (treeString);
    }

    private void makeString(DefaultMutableTreeNode dmtn, StringBuffer rtn, int level) {
        String name = dmtn.getUserObject().toString();
        boolean leaf = dmtn.isLeaf();
        boolean expandable = dmtn.getChildCount() > 0;
        indent(rtn, level);
        String badge = "";
        boolean collapsed = isCollasped(dmtn);
        if (!leaf) {
            if (collapsed) {
                badge = "(+)";
            } else {
                badge = "(-)";
            }
        }

        String checkBox = "";
        if (leaf) {
            checkBox = "<input type=\"checkbox\" value=\"" + name + "\"/>";
        }

        rtn.append(" <b>" + checkBox + "<a href=\"index.jsp?treeClick=" + name + "\">" + badge + name + " </a></b><br>    ");
        if (!collapsed) {
            Enumeration e = dmtn.children();
            level++;
            while (e.hasMoreElements()) {
                DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement();
                makeString(n, rtn, level);
            }
        }
    }

    public static String prettyArray(Object oa[]) {
        StringBuffer rtn = new StringBuffer(oa.length * 10);
        rtn.append("[");
        for (Object o : oa) {
            rtn.append(o.toString() + ',');
        }
        rtn = rtn.delete(rtn.length() - 1, rtn.length());    // trim off that last comma
        rtn.append(']');
        return (rtn.toString());
    }

    private void setCollapsed(boolean b, DefaultMutableTreeNode dmtn) {
        if (b) {
            collaspedSet.add(dmtn);
        } else {
            collaspedSet.remove(dmtn);
        }
    }

    private boolean isCollasped(DefaultMutableTreeNode dmtn) {
        return (collaspedSet.contains(dmtn));

    }

    private void indent(StringBuffer rtn, int count) {
        for (int a = 0; a < count; a++) {
            rtn.append("&nbsp;");
        }

    }

    public String getButtons() {
        if (buttonText == null) {
            buttonText = new StringBuffer(255);
            buttonText.append(makeButton("Save", "Save", true));
            buttonText.append(makeButton("Compile", "Compile", true));
            buttonText.append(makeButton("Test", "Test", true));
            buttonText.append(makeButton("Edit", "Edit", editEnabled));
            buttonText.append(makeButton("New", "New", true));
            buttonText.append(makeButton("Logout", "Logout", true));
            buttonText.append(makeButton("New UI", "New UI", true));
        }
        return (buttonText.toString());
    }

    private String makeButton(String name, String value, boolean enabled) {
        if (enabled) {
            return ("<input name=\"" + name + "\" value=\"" + value + "\" type=\"submit\"\n ");
        } else {
            return ("<input name=\"" + name + "\" value=\"" + value + "\" type=\"submit\" disabled=\"true\"\n");
        }

    }

    public void treeSelection(String s) {

    }

    public void buttonPress(String button, String marked[]) {

    }

    public static String getUserPassword(final String username) throws SQLException, ClassNotFoundException {
        Connection con = getConnection();
        String pass = null;
        try {
            PreparedStatement ps = con.prepareStatement("select user_pass from users where user_name=?");
            ps.setString(1, username);
            ResultSet rs = ps.executeQuery();
            rs.next();
            pass = rs.getString(1);
        }
        catch (SQLException e) {
            con.close();
        }
        finally {
            con.close();
        }
        return (pass);
    }
}
